Skip to content

fix: replace az CLI token acquisition with MSAL.NET to eliminate proy resets#324

Merged
sellakumaran merged 3 commits intomainfrom
users/sellak/msal-direct-token-acquisition
Mar 27, 2026
Merged

fix: replace az CLI token acquisition with MSAL.NET to eliminate proy resets#324
sellakumaran merged 3 commits intomainfrom
users/sellak/msal-direct-token-acquisition

Conversation

@sellakumaran
Copy link
Copy Markdown
Contributor

Users on corporate networks with TLS inspection proxies (Zscaler, Netskope)
intermittently saw ConnectionResetError (10054) during 'a365 setup all'. The
failure was non-deterministic — different steps each run, restarting sometimes
helped.

Root cause: all token acquisition called 'az account get-access-token' as a
subprocess. The Azure CLI is Python-based and uses an HTTP connection pool that
the TLS proxy would reset mid-execution during longer commands.

Fix has two layers:

  1. Token acquisition: replaced all subprocess calls with direct MSAL.NET via
    AuthenticationService. On Windows, MSAL uses WAM — an OS-level broker that
    communicates over IPC, bypassing the proxy entirely. On macOS/Linux, MSAL
    uses browser or device code flow.

  2. API call resilience: ARM and Graph HTTP calls are now wrapped with
    RetryHelper. If the proxy resets the actual API call (not the token), the
    retry succeeds without user intervention — automating the "restart and it
    works" workaround users were applying manually.

Additional changes:

  • AzCliHelper retains only login-hint resolution; token acquisition removed
  • BotConfigurator reads tenantId from config instead of 'az account show'
  • NetworkHelper centralises connection-reset detection and warning message
  • AuthenticationService gains ResolveLoginHintFromCacheAsync as fallback when
    az CLI is not available
  • Added tests for ResolveLoginHintFromCacheAsync and NetworkHelper

Closes #321

…y resets (#321)

Users on corporate networks with TLS inspection proxies
intermittently saw ConnectionResetError (10054) during 'a365 setup all'. The
failure was non-deterministic — different steps each run, restarting sometimes
helped.

Root cause: all token acquisition called 'az account get-access-token' as a
subprocess. The Azure CLI is Python-based and uses an HTTP connection pool that
the TLS proxy would reset mid-execution during longer commands.

Fix: replaced all subprocess token acquisition with direct MSAL.NET calls via
AuthenticationService. On Windows, MSAL uses WAM — an OS-level broker that
communicates over IPC, bypassing the proxy entirely. On macOS/Linux, MSAL uses
browser or device code flow.

Changes:
- GraphApiService and ArmApiService now acquire tokens via IAuthenticationService
  (MSAL) instead of spawning 'az account get-access-token' subprocesses
- AzCliHelper retains only login-hint resolution (az account show); token
  acquisition methods removed
- BotConfigurator reads tenantId from config instead of 'az account show'
- NetworkHelper centralises connection-reset detection and warning message
- RetryHelper accepts constructor-level defaults; injectable in tests to skip
  backoff delays
- AuthenticationService gains ResolveLoginHintFromCacheAsync as fallback when
  az CLI is not available
- Added tests for ResolveLoginHintFromCacheAsync and NetworkHelper
Copilot AI review requested due to automatic review settings March 27, 2026 01:02
@sellakumaran sellakumaran requested review from a team as code owners March 27, 2026 01:02
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA cadebaa.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces Azure CLI subprocess-based token acquisition (az account get-access-token) with MSAL.NET-based acquisition via AuthenticationService, and adds connection-reset diagnostics/retry behavior intended to mitigate intermittent proxy/TLS inspection resets during a365 setup all and related flows.

Changes:

  • Introduces IAuthenticationService and updates Graph/ARM services and tests to use MSAL-based token acquisition instead of Azure CLI token calls.
  • Adds NetworkHelper for connection-reset detection and integrates RetryHelper into selected HTTP paths.
  • Updates setup/bot flows and docs/changelog to reflect the new authentication and resilience architecture.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/Helpers/NetworkHelperTests.cs Adds unit tests for connection-reset detection.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/Helpers/AzCliHelperTests.cs Removes Azure CLI token cache tests; keeps login-hint cache tests.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceVerifyInheritablePermissionsTests.cs Updates GraphApiService construction to inject auth service.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTokenTrimTests.cs Updates token trimming tests to use IAuthenticationService stubs.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTokenCacheTests.cs Removes tests tied to the old AzCliHelper token cache behavior.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTests.cs Updates GraphApiService tests to use IAuthenticationService and retry helper injection.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceIsApplicationOwnerTests.cs Updates tests away from az CLI token mocking to IAuthenticationService.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceAddRequiredResourceAccessTests.cs Updates blueprint permission tests to inject IAuthenticationService.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/ClientAppValidatorTests.cs Adjusts imports for updated validator dependencies.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/AuthenticationServiceTests.cs Adds tests for ResolveLoginHintFromCacheAsync.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/ArmApiServiceTests.cs Updates ARM tests to inject IAuthenticationService and retry helper.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/AgentBlueprintServiceTests.cs Updates GraphApiService construction to include auth service.
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/CleanupCommandTests.cs Updates GraphApiService construction signature (auth service param).
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/CleanupCommandBotEndpointTests.cs Updates GraphApiService construction signature (auth service param).
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/BlueprintSubcommandTests.cs Simplifies GraphApiService partial substitute construction after signature change.
src/Microsoft.Agents.A365.DevTools.Cli/design.md Documents MSAL-based authentication architecture and caching behavior.
src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/RetryHelper.cs Makes retry parameters configurable via ctor/defaults; supports overrides per call.
src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/NetworkHelper.cs Adds shared connection-reset detection and warning message.
src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/AzCliHelper.cs Removes token acquisition; retains login-hint resolution via az account show.
src/Microsoft.Agents.A365.DevTools.Cli/Services/GraphApiService.cs Switches token acquisition to IAuthenticationService; adds retry + proxy-reset diagnostics in some paths.
src/Microsoft.Agents.A365.DevTools.Cli/Services/DelegatedConsentService.cs Updates fresh-token acquisition to use GraphApiService/MSAL path.
src/Microsoft.Agents.A365.DevTools.Cli/Services/ClientAppValidator.cs Removes AzCli token cache invalidation; retries on 401.
src/Microsoft.Agents.A365.DevTools.Cli/Services/BotConfigurator.cs Reads tenantId from config; resolves login hint via az CLI or MSAL cache.
src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs Introduces IAuthenticationService and adds ResolveLoginHintFromCacheAsync (JWT decode).
src/Microsoft.Agents.A365.DevTools.Cli/Services/ArmApiService.cs Switches ARM token acquisition to MSAL (IAuthenticationService) and wraps GETs with retry helper.
src/Microsoft.Agents.A365.DevTools.Cli/Program.cs Registers IAuthenticationService in DI backed by AuthenticationService.
src/Microsoft.Agents.A365.DevTools.Cli/Commands/SetupSubcommands/InfrastructureSubcommand.cs Removes eager ARM token prefetch; defers to ARM service lazy acquisition.
src/Microsoft.Agents.A365.DevTools.Cli/Commands/SetupSubcommands/BlueprintSubcommand.cs Constructs delegated-consent GraphApiService with MSAL-based auth service.
CHANGELOG.md Adds entry for fixing intermittent connection reset failures (#321).

ajmfehr
ajmfehr previously approved these changes Mar 27, 2026
Add forceRefresh to Graph token flow; improve testability

Introduce a forceRefresh parameter to Microsoft Graph token acquisition, allowing explicit cache bypass and fresh token retrieval. Update IMicrosoftGraphTokenProvider and MicrosoftGraphTokenProvider to support this, and refactor GraphApiService to propagate forceRefresh throughout token and header acquisition. Update all call sites to use named arguments for clarity. Enhance ClientAppValidator and related tests to exercise token refresh logic. Improve test setup for GraphApiService and fix JWT Base64Url encoding/decoding in AuthenticationService and tests. These changes increase reliability and testability, especially for scenarios involving token revocation or conditional access.
Changed log statements in AuthenticationService from Information to Debug to reduce log verbosity. Added a unit test to ensure forceRefresh bypasses the token cache in MicrosoftGraphTokenProvider.
@sellakumaran sellakumaran merged commit 45e271f into main Mar 27, 2026
8 checks passed
@sellakumaran sellakumaran deleted the users/sellak/msal-direct-token-acquisition branch March 27, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

a365 setup all intermittently fails with ConnectionResetError (10054) during tenant setup

4 participants